package com.youxin.foundation.utils.collections;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import com.youxin.foundation.interfaces.Convert2;
import com.youxin.foundation.utils.StringUtils;

/**
 * 集合工具类方法
 * 
 * @author yingde.cao
 *
 */
public class CollectionsUtils {
	/**
	 * 合并列表
	 * 
	 * @param list1
	 *            列表1
	 * @param list2
	 *            列表2
	 * @return List<T>
	 */
	public static <T> List<T> combine(List<T> list1, List<T> list2) {
		Set<T> set = new HashSet<>();
		set.addAll(list1);
		set.addAll(list2);
		List<T> result = new ArrayList<>(set);
		return result;
	}

	public static <T> int interIndex(List<T> list1, List<T> list2) {
		if(list1==null||list2==null){
			return -1;
		}
		for (T t : list2) {
			return list1.indexOf(t);
		}
		return -1;
	}

	/**
	 * 交集
	 * 
	 * @param list1
	 * @param list2
	 * @return List
	 */
	public static <T> List<T> interItems(List<T> list1, List<T> list2) {
		Set<T> set = new HashSet<>();
		set.addAll(list1);

		Set<T> set2 = new HashSet<>();
		set2.addAll(list2);
		set.retainAll(set2);
		return new ArrayList<>(set);
	}

	public static String join(List<String> list, String separator) {
		return org.apache.commons.lang.StringUtils.join(list.toArray(), separator);
	}

	public static long getLongValue(Map<String, String> keysAndValues, String key) {
		try {
			String value = keysAndValues.get(key);
			if (StringUtils.isNullOrEmpty(value)) {
				return 0;
			}
			return Long.valueOf(value);
		} catch (Exception e) {
			return 0;
		}
	}

	/**
	 * Map中的值递增1
	 * 
	 * @param keysAndValues
	 * @param key
	 * @return
	 */
	public static long incrementMap(Map<String, String> keysAndValues, String key) {
		long val = getLongValue(keysAndValues, key);
		++val;
		keysAndValues.put(key, String.valueOf(val));
		return val;
	}

	public static long incrementMap(Map<String, String> keysAndValues, String key, long times) {
		long val = getLongValue(keysAndValues, key);
		val += times;
		keysAndValues.put(key, String.valueOf(val));
		return val;
	}

	public static Long incrementLong(Map<String, Long> keysAndValues, String key) {
		Long val = keysAndValues.get(key);
		if (val != null) {
			++val;
		} else {
			val = 1L;
		}
		keysAndValues.put(key, val);
		return val;
	}

	public static Long incrementLong(Map<String, Long> keysAndValues, String key, long times) {
		Long val = keysAndValues.get(key);
		if (val != null) {
			val += times;
		} else {
			val = times;
		}
		keysAndValues.put(key, val);
		return val;
	}

	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
		Map<K, V> result = new LinkedHashMap<>();
		Stream<Entry<K, V>> st = map.entrySet().stream();

		st.sorted(Comparator.comparing(e -> e.getValue())).forEach(e -> result.put(e.getKey(), e.getValue()));

		return result;
	}

	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAsc(Map<K, V> map) {
		return sortByValueList(map, new Comparator<Map.Entry<K, V>>() {
			@Override
			public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
				return (o1.getValue()).compareTo(o2.getValue());
			}
		});
	}

	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDesc(Map<K, V> map) {
		return sortByValueList(map, new Comparator<Map.Entry<K, V>>() {
			@Override
			public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
				return (o2.getValue()).compareTo(o1.getValue());
			}
		});
	}

	/**
	 * 根据map value值排序
	 * 
	 * @param map
	 * @param comparator
	 * @return
	 */
	public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueList(Map<K, V> map,
			Comparator<Map.Entry<K, V>> comparator) {
		List<Map.Entry<K, V>> list = new ArrayList<>(map.entrySet());
		Collections.sort(list, comparator);
		Map<K, V> result = new LinkedHashMap<>();
		for (Map.Entry<K, V> entry : list) {
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}

	/**
	 * Iterable to List
	 * 
	 * @param iterable
	 *            Iterable
	 * @return List
	 */
	public static <T> List<T> toList(final Iterable<T> iterable) {
		return StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
	}

	/**
	 * Map全并成字符串
	 * 
	 * @param map
	 * @param keyjoinString
	 * @param itemJoinString
	 * @return
	 */
	public static String mapToString(Map<String, String> map, String keyjoinString, String itemJoinString) {
		return map.entrySet().stream().map(entry -> entry.getKey() + keyjoinString + entry.getValue())
				.collect(Collectors.joining(itemJoinString));
	}

	@SuppressWarnings("unchecked")
	public static <T, P> List<P> listClassConvert(List<T> lists) {
		return (List<P>) (List<?>) lists;
	}
	
	/**
	 * 获取类转换列表中的数据,类似,获取List<Contact>转换为List<String>
	 * @param lists
	 * @param convert
	 * @return
	 */
	public static <T, P> List<P> listPropertyName(List<T> lists,Convert2<T, P> convert)
	{
		return lists.stream().map(
				(item)->{
					return convert.apply(item);
				}
		).collect(Collectors.toList());
	}

}
